package cn.yangjunda.multipart.commons;

import cn.yangjunda.multipart.exception.MaxUploadSizeExceededException;
import cn.yangjunda.multipart.exception.MultipartException;
import cn.yangjunda.multipart.MultipartFile;
import cn.yangjunda.multipart.MultipartResolver;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author Juanda
 * @Description
 * @date 2017/12/19 9:21
 */
public class CommonsMultipartResolver extends CommonsFileUploadSupport implements MultipartResolver {


    @Override
    public MultipartFile resolveMultipart(HttpServletRequest request) {
        return parseRequest(request);
    }

    @Override
    protected ServletFileUpload newFileUpload(DiskFileItemFactory fileItemFactory) {
        ServletFileUpload upload = new ServletFileUpload(fileItemFactory);

        // 设置最大文件上传值
        upload.setFileSizeMax(MAX_FILE_SIZE);

        // 设置最大请求值 (包含文件和表单数据)
        upload.setSizeMax(MAX_REQUEST_SIZE);

        return upload;
    }

    private MultipartFile parseRequest(HttpServletRequest request) throws MultipartException {
        ServletFileUpload fileUpload = prepareFileUpload();
        try {
            List<FileItem> fileItems = fileUpload.parseRequest(request);
            return parseFileItems(fileItems);
        }
        catch (FileUploadBase.SizeLimitExceededException ex) {
            throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
        }
        catch (FileUploadBase.FileSizeLimitExceededException ex) {
            throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex);
        }
        catch (FileUploadException ex) {
            throw new MultipartException("Failed to parse multipart servlet request", ex);
        }
    }

    private MultipartFile parseFileItems(List<FileItem> fileItems) {
        if (fileItems != null && fileItems.size() > 0) {
            FileItem item = fileItems.get(0);
            // 迭代表单数据
            // 处理不在表单中的字段
            if (!item.isFormField()) {
                return new CommonsMultipartFile(item);
            }
        }
        return null;
    }
}
